{
 "cells": [
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "# 创建与接口对话的智能体应用\n",
    "## 1.导入 sql 创建 db"
   ],
   "id": "48d649fe98160bc3"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "###  sqlite3 hydrology.db < hydrology.sql\n",
   "id": "edcc161c229cf72"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "## 2.启动 hydrology_app.py flask 服务",
   "id": "c445c6ab1105e385"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "## 3. 构建智能体应用\n",
    "### 3.1 加载 LLM 的环境变量"
   ],
   "id": "fa141e5d9d33be57"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-11-20T08:13:39.732721Z",
     "start_time": "2024-11-20T08:13:39.723881Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from dotenv import load_dotenv\n",
    "import os\n",
    "\n",
    "# 加载 .env 文件\n",
    "load_dotenv()\n",
    "\n",
    "# 读取环境变量\n",
    "API_BASE_URL = os.getenv(\"API_BASE_URL\")\n",
    "API_KEY = os.getenv(\"API_KEY\")\n",
    "\n",
    "print(\"API_BASE_URL:\", API_BASE_URL)"
   ],
   "id": "c6a2c6153cc3afd9",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "API_BASE_URL: https://cognihubemp.baystoneai.com/cognihub/service\n"
     ]
    }
   ],
   "execution_count": 1
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-11-20T08:13:40.708481Z",
     "start_time": "2024-11-20T08:13:39.736068Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from langchain_openai import ChatOpenAI\n",
    "\n",
    "CHAT_MODEL = \"qwen2.5-instruct\"\n",
    "model = ChatOpenAI(\n",
    "    model=CHAT_MODEL,\n",
    "    base_url=f'{API_BASE_URL}/v1',\n",
    "    api_key=API_KEY,\n",
    "    temperature=0,\n",
    "    streaming=True\n",
    ")"
   ],
   "id": "ff7531270f24fe18",
   "outputs": [],
   "execution_count": 2
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "### 3.2 创建智能体理解数据的模版",
   "id": "3f51a8a62fbb452"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-11-20T08:13:40.743817Z",
     "start_time": "2024-11-20T08:13:40.741877Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from langchain_core.prompts import PromptTemplate\n",
    "\n",
    "# 定义 Prompt 模板\n",
    "template = \"\"\"\n",
    "你是一名水文专家，以下是某个站点的水文数据：\n",
    "站点名称：{station_name}\n",
    "当前水位：{current_level} 米\n",
    "警戒水位：{alert_level} 米\n",
    "最近水位数据（时间和水位）：\n",
    "{recent_data}\n",
    "\n",
    "请根据以上数据回答以下问题：\n",
    "{question}\n",
    "\"\"\"\n",
    "prompt = PromptTemplate(\n",
    "    input_variables=[\"station_name\", \"current_level\", \"alert_level\", \"recent_data\", \"question\"],\n",
    "    template=template\n",
    ")\n",
    "\n",
    "# 创建问答链\n",
    "qa_chain = prompt | model"
   ],
   "id": "ae4c80e73cf5980",
   "outputs": [],
   "execution_count": 3
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "### 3.3 创建处理站点名称的函数",
   "id": "2d62ce19c84e3308"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-11-20T08:13:40.749045Z",
     "start_time": "2024-11-20T08:13:40.747527Z"
    }
   },
   "cell_type": "code",
   "source": [
    "def extract_station_name(question):\n",
    "    \"\"\"\n",
    "    从问题中提取站点名称。\n",
    "    支持常见河流或站点关键字，例如：长江、黄河、东江。\n",
    "    \"\"\"\n",
    "    station_names = [\"长江\", \"黄河\", \"东江\"]  # 定义支持的站点名称\n",
    "    for station in station_names:\n",
    "        if station in question:\n",
    "            return station\n",
    "    return None"
   ],
   "id": "bc7ec52abcd09f17",
   "outputs": [],
   "execution_count": 4
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "### 3.4 调用 flask 服务中的接口获取相关的数据",
   "id": "7baec6aecfc3616b"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-11-20T08:13:40.755247Z",
     "start_time": "2024-11-20T08:13:40.752883Z"
    }
   },
   "cell_type": "code",
   "source": [
    "import json\n",
    "import requests\n",
    "\n",
    "# 定义问答函数\n",
    "def analyze_water_level_trend(question):\n",
    "    # 提取站点名称\n",
    "    station_name = extract_station_name(question)\n",
    "    if not station_name:\n",
    "        return \"无法识别问题中的站点名称，请明确指定站点，例如：长江、黄河或东江。\"\n",
    "    # 调用 Flask 接口\n",
    "    response = requests.post(\"http://127.0.0.1:5000/current_water_level\", json={\"station_name\": station_name})\n",
    "    if response.status_code != 200:\n",
    "        print(f\"Error: Received status code {response.status_code}\")\n",
    "        print(f\"Response text: {response.text}\")\n",
    "        exit()\n",
    "\n",
    "    # 确认返回的是有效 JSON\n",
    "    try:\n",
    "        data = response.json()\n",
    "    except json.JSONDecodeError as e:\n",
    "        print(f\"JSON decode error: {e}\")\n",
    "        print(f\"Response text: {response.text}\")\n",
    "        exit()\n",
    "\n",
    "    print(\"Parsed data:\", data)\n",
    "    alert_level = data[\"alert_level\"]\n",
    "    recent_data_list = data[\"recent_data\"]  # 原始字典列表\n",
    "    recent_data = \"\\n\".join(\n",
    "        [f\"时间: {entry['time']}, 水位: {entry['precipitation']}m\" for entry in data[\"recent_data\"]]\n",
    "    )\n",
    "    current_level = recent_data_list[0][\"precipitation\"]  # 直接提取最新水位\n",
    "\n",
    "    # 调用 LangChain 生成回答\n",
    "    answer = qa_chain.invoke({\"station_name\": station_name, \"current_level\": current_level, \"alert_level\": alert_level, \"recent_data\": recent_data, \"question\": question})\n",
    "    return answer.content"
   ],
   "id": "3c18cb3766a66234",
   "outputs": [],
   "execution_count": 5
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "### 3.5测试智能体",
   "id": "3b52b973ffc4749b"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-11-20T08:13:46.640956Z",
     "start_time": "2024-11-20T08:13:40.759242Z"
    }
   },
   "cell_type": "code",
   "source": "analyze_water_level_trend(\"长江现在水位是多少？\")",
   "id": "5eeaaf94638f9092",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Parsed data: {'alert_level': 15.0, 'recent_data': [{'precipitation': 2.8, 'time': '2024-11-18 09:00:00'}, {'precipitation': 3.0, 'time': '2024-11-18 08:00:00'}, {'precipitation': 3.2, 'time': '2024-11-18 07:00:00'}, {'precipitation': 3.5, 'time': '2024-11-18 06:00:00'}, {'precipitation': 3.8, 'time': '2024-11-18 05:00:00'}]}\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'根据提供的数据，长江当前的水位是2.8米。这是在2024年11月18日09:00:00记录的水位。'"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 6
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "### 3.6 创建一个消息回复模版",
   "id": "15966409824f0362"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-11-20T08:13:46.648482Z",
     "start_time": "2024-11-20T08:13:46.646517Z"
    }
   },
   "cell_type": "code",
   "source": [
    "def format_message_template(question, answer, user_name=\"隔壁老王\", assistant_name=\"英智玲珑\"):\n",
    "    \"\"\"\n",
    "    使用消息模板格式化输出。\n",
    "\n",
    "    参数:\n",
    "        question (str): 用户提出的问题。\n",
    "        answer (str): 系统生成的回答。\n",
    "        user_name (str): 用户称呼（默认为“用户”）。\n",
    "        assistant_name (str): 助理称呼（默认为“您的助理”）。\n",
    "\n",
    "    返回:\n",
    "        str: 格式化的消息。\n",
    "    \"\"\"\n",
    "    message_template = f\"\"\"\n",
    "    尊敬的 [{user_name}]：\n",
    "\n",
    "    您好！\n",
    "\n",
    "    以下是您提出的问题：\n",
    "    问：{question}\n",
    "\n",
    "    我的回答如下：\n",
    "    答：{answer}\n",
    "\n",
    "    谢谢！\n",
    "\n",
    "    [{assistant_name}]\n",
    "    \"\"\"\n",
    "    return message_template"
   ],
   "id": "25e475abeefac15b",
   "outputs": [],
   "execution_count": 7
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "## 4. 测试智能体\n",
    "### 4.1 测试用例 一"
   ],
   "id": "f063e74739c49252"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-11-20T08:13:48.936936Z",
     "start_time": "2024-11-20T08:13:46.654336Z"
    }
   },
   "cell_type": "code",
   "source": [
    "question_1 = \"长江现在水位是多少？\"\n",
    "answer_1 = analyze_water_level_trend(question_1)\n",
    "message_1 = format_message_template(question_1, answer_1)\n",
    "print(message_1)"
   ],
   "id": "25ee4c5de8d07d67",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Parsed data: {'alert_level': 15.0, 'recent_data': [{'precipitation': 2.8, 'time': '2024-11-18 09:00:00'}, {'precipitation': 3.0, 'time': '2024-11-18 08:00:00'}, {'precipitation': 3.2, 'time': '2024-11-18 07:00:00'}, {'precipitation': 3.5, 'time': '2024-11-18 06:00:00'}, {'precipitation': 3.8, 'time': '2024-11-18 05:00:00'}]}\n",
      "\n",
      "    尊敬的 [隔壁老王]：\n",
      "\n",
      "    您好！\n",
      "\n",
      "    以下是您提出的问题：\n",
      "    问：长江现在水位是多少？\n",
      "\n",
      "    我的回答如下：\n",
      "    答：根据提供的数据，长江当前的水位是2.8米。这是在2024年11月18日09:00:00记录的水位。\n",
      "\n",
      "    谢谢！\n",
      "\n",
      "    [英智玲珑]\n",
      "    \n"
     ]
    }
   ],
   "execution_count": 8
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "### 4.2 测试用例 二",
   "id": "d8dd8cb426c3dda"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-11-20T08:13:52.495474Z",
     "start_time": "2024-11-20T08:13:48.950810Z"
    }
   },
   "cell_type": "code",
   "source": [
    "question_2 = \"长江水位是否超限？\"\n",
    "answer_2 = analyze_water_level_trend(question_2)\n",
    "message_2 = format_message_template(question_2, answer_2)\n",
    "print(message_2)"
   ],
   "id": "af1ad5c575617c4f",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Parsed data: {'alert_level': 15.0, 'recent_data': [{'precipitation': 2.8, 'time': '2024-11-18 09:00:00'}, {'precipitation': 3.0, 'time': '2024-11-18 08:00:00'}, {'precipitation': 3.2, 'time': '2024-11-18 07:00:00'}, {'precipitation': 3.5, 'time': '2024-11-18 06:00:00'}, {'precipitation': 3.8, 'time': '2024-11-18 05:00:00'}]}\n",
      "\n",
      "    尊敬的 [隔壁老王]：\n",
      "\n",
      "    您好！\n",
      "\n",
      "    以下是您提出的问题：\n",
      "    问：长江水位是否超限？\n",
      "\n",
      "    我的回答如下：\n",
      "    答：根据提供的数据，长江当前的水位为2.8米，而警戒水位为15.0米。因此，当前水位并未超过警戒水位，水位处于安全范围内。\n",
      "\n",
      "    谢谢！\n",
      "\n",
      "    [英智玲珑]\n",
      "    \n"
     ]
    }
   ],
   "execution_count": 9
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "### 4.3 测试用例 三",
   "id": "11c88116751171ee"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-11-20T08:13:57.311062Z",
     "start_time": "2024-11-20T08:13:52.503284Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 示例问题 3: 长江水位变化趋势是什么？\n",
    "question_3 = \"长江水位变化趋势是什么？\"\n",
    "answer_3 = analyze_water_level_trend(question_3)\n",
    "message_3 = format_message_template(question_3, answer_3)\n",
    "print(message_3)"
   ],
   "id": "aaaf543a2a84d84d",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Parsed data: {'alert_level': 15.0, 'recent_data': [{'precipitation': 2.8, 'time': '2024-11-18 09:00:00'}, {'precipitation': 3.0, 'time': '2024-11-18 08:00:00'}, {'precipitation': 3.2, 'time': '2024-11-18 07:00:00'}, {'precipitation': 3.5, 'time': '2024-11-18 06:00:00'}, {'precipitation': 3.8, 'time': '2024-11-18 05:00:00'}]}\n",
      "\n",
      "    尊敬的 [隔壁老王]：\n",
      "\n",
      "    您好！\n",
      "\n",
      "    以下是您提出的问题：\n",
      "    问：长江水位变化趋势是什么？\n",
      "\n",
      "    我的回答如下：\n",
      "    答：根据提供的水文数据，我们可以看到长江的水位在2024年11月18日从05:00到09:00期间呈现下降的趋势。具体来说，水位从05:00的3.8米下降到09:00的2.8米。因此，可以得出结论，长江的水位在这段时间内是逐渐下降的。\n",
      "\n",
      "    谢谢！\n",
      "\n",
      "    [英智玲珑]\n",
      "    \n"
     ]
    }
   ],
   "execution_count": 10
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "### 4.4 测试用例 四",
   "id": "cf690719f22029de"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-11-20T08:14:05.559319Z",
     "start_time": "2024-11-20T08:13:57.321470Z"
    }
   },
   "cell_type": "code",
   "source": [
    "question_4 = \"长江现在水位是多少？是否超限？未来趋势是怎么样的？\"\n",
    "answer_4 = analyze_water_level_trend(question_4)\n",
    "message_4 = format_message_template(question_4, answer_4)\n",
    "print(message_4)"
   ],
   "id": "bd45aa3f857987e2",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Parsed data: {'alert_level': 15.0, 'recent_data': [{'precipitation': 2.8, 'time': '2024-11-18 09:00:00'}, {'precipitation': 3.0, 'time': '2024-11-18 08:00:00'}, {'precipitation': 3.2, 'time': '2024-11-18 07:00:00'}, {'precipitation': 3.5, 'time': '2024-11-18 06:00:00'}, {'precipitation': 3.8, 'time': '2024-11-18 05:00:00'}]}\n",
      "\n",
      "    尊敬的 [隔壁老王]：\n",
      "\n",
      "    您好！\n",
      "\n",
      "    以下是您提出的问题：\n",
      "    问：长江现在水位是多少？是否超限？未来趋势是怎么样的？\n",
      "\n",
      "    我的回答如下：\n",
      "    答：根据提供的数据，长江当前的水位是2.8米，这低于警戒水位15.0米，因此当前水位并未超限。\n",
      "\n",
      "从最近的水位数据来看，水位在逐渐下降。具体来说，从2024年11月18日05:00到09:00，水位从3.8米下降到了2.8米。这种趋势表明，水位正在减少，如果这种趋势继续下去，未来水位可能会进一步下降。不过，需要注意的是，水位的变化可能受到多种因素的影响，包括降雨、上游来水、水库调度等，因此未来水位的具体变化还需要结合实时气象和水文信息进行综合分析。\n",
      "\n",
      "    谢谢！\n",
      "\n",
      "    [英智玲珑]\n",
      "    \n"
     ]
    }
   ],
   "execution_count": 11
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
